/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// <list_utils.h> - List module.                                           //
//                                                                         //
// Version :        0.0.1                                                  //
// Language :       C                                                      //
// Platform :       Linux                                                  //
// Application :                                                           //
// Author :         Ireta                                                  //
// Created Date :   2012_08_08                                             //
// Header :                                                                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//                           Maintenance                                   //
/////////////////////////////////////////////////////////////////////////////

/*
 Version  Modified By  Date        Remarks
 =============================================================================
 0.0.1	   Ireta        2012-08-08  Basic initiate
 */

#ifndef LIST_UTILS_H
#define LIST_UTILS_H

/////////////////////////////////////////////////////////////////////////////
//                           Headers                                       //
/////////////////////////////////////////////////////////////////////////////

#include <stdbool.h>

#include "common.h"

# ifdef __cplusplus
extern "C" {
# endif

/////////////////////////////////////////////////////////////////////////////
//                      Data Structure Declarations                        //
/////////////////////////////////////////////////////////////////////////////

typedef struct ListNode {
	void* data; // The node's data, must be malloc & free carefully

	struct ListNode* previous; // The pointer point to previous node
	struct ListNode* next; // The pointer point to next node
} ListNode;

typedef struct ListIterator {
	int index; // The current node's index in List

    struct List*     root;    // List root
	struct ListNode* current; // Current node
} ListIterator;

typedef struct List {
	int size; // The size of List nodes

	struct ListNode* first; // First node in the List
	struct ListNode* last; // Last node in the List
} List;

typedef struct ListKeyValue {
	char key[STRING_MID_LENGTH]; //max: CWMP_NAME_LENGTH
	void* value;
} ListKeyValue;

/////////////////////////////////////////////////////////////////////////////
//                   Public Interface Declarations                         //
/////////////////////////////////////////////////////////////////////////////

/* List initialization function, must be called first */
void List_init(List* root);

/* List operation functions */
// Get first node of List.
ListNode* List_getFirst(List* root);
// Get last node of List.
ListNode* List_getLast(List* root);
void* List_get(List* root, int position);

/* First in & First out operation functions */
// Push a data into List.  Target data will be appened as last node of List.
void List_push(List* root, void* data);
// Pop a data from List.  Target data will be the first node in List.
void* List_pop(List* root);

/* Remove operation functions */
// Remove data from List.
bool List_removeData(List* root, void* data, bool isFreeData);
// Remove data from List and callback.
bool List_removeDataWithCallback(List* root, void* data, void (*callback)(void* data));
// Remove node from List.
void List_removeNode(List* root, ListNode* target, bool isFreeData);
// Remove node from List and callback.
void List_removeNodeWithCallback(List* root, ListNode* target, void (*callback)(void* data));
// Clear all nodes in List and free all data.
void List_clear(List* root);
// Clear all nodes in List and callback.
void List_clearWithCallback(List* root, void (*callback)(void* data));

/* Iterator operation functions */
// Get List iterator.
void List_getIterator(List* root, ListIterator* iterator);
// Validate if there still has next node or not.
bool List_hasNext(ListIterator* iterator);
// Validate if there still has previous node or not.
bool List_hasPrevious(ListIterator* iterator);
// Move iterator to next node.
void* List_next(ListIterator* iterator);
// Move iterator to previous node.
void* List_previous(ListIterator* iterator);

// Remove current iterator node and move to next node.
// This function can be used when using hasPrevious() & previous()
bool List_removeAndNext(List* root, ListIterator* iterator, bool isFreeData);
// Remove current iterator node and move to next node and callback.
// This function can be used when using hasPrevious() & previous()
bool List_removeAndNextWithCallback(List* root, ListIterator* iterator, void (*callback)(void* data));

// Remove current iterator node and move to previous node.
// This function can be used when using hasNext() & next().
bool List_removeAndPrevious(List* root, ListIterator* iterator, bool isFreeData);
// Remove current iterator node and move to previous node and callback.
// This function can be used when using hasNext() & next().
bool List_removeAndPreviousWithCallback(List* root, ListIterator* iterator, void (*callback)(void* data));

// clone Iterator
void List_cloneIterator(ListIterator* source, ListIterator* target);

# ifdef __cplusplus
}
# endif

#endif // LIST_UTILS_H
